import { useApiSettings } from '../contexts/ApiSettingsContext';
import { EmbeddingService } from './EmbeddingService';

// 检索结果接口
export interface RetrievalResult {
  id: string;
  title: string;
  content: string;
  source: string;
  score: number;
  metadata: Record<string, any>;
  vector?: number[];
}

// 检索请求接口
export interface RetrievalRequest {
  query: string;
  topK: number;
  similarityThreshold: number;
  filter?: Record<string, any>;
  hybridSearch: boolean;
  includeVectors?: boolean;
  namespace?: string;
}

// 检索服务类
export class RetrievalService {
  private apiSettings;
  private embeddingService: EmbeddingService;

  constructor() {
    const { apiSettings } = useApiSettings();
    this.apiSettings = apiSettings.retrieval;
    this.embeddingService = new EmbeddingService();
  }

  // 向量检索方法
  async vectorSearch(queryText: string, topK: number = 10, threshold: number = 0.7): Promise<RetrievalResult[]> {
    try {
      // 1. 使用EmbeddingService获取查询文本的嵌入向量
      const queryVector = await this.embeddingService.embedText(queryText);
      
      // 2. 实际中向向量数据库发送请求
      // 这里使用模拟数据
      await new Promise(resolve => setTimeout(resolve, 500 + Math.random() * 500));
      
      // 3. 生成随机结果 - 在真实应用中这里会从向量数据库返回
      const results: RetrievalResult[] = [];
      
      for (let i = 0; i < topK; i++) {
        // 生成递减的相似度分数
        const score = Math.max(0.4, 0.95 - (i * 0.05) + (Math.random() * 0.1 - 0.05));
        
        // 只返回超过阈值的结果
        if (score >= threshold) {
          results.push({
            id: `doc-${i + 1}`,
            title: `${queryText} 相关文档 ${i + 1}`,
            content: `这是一个与查询"${queryText}"相关的文档内容示例。这段内容模拟从向量数据库中检索到的文档片段，相似度得分为 ${score.toFixed(2)}。`,
            source: `https://example.com/docs/${i + 1}`,
            score: score,
            metadata: {
              createdAt: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toISOString(),
              author: ['张三', '李四', '王五', '赵六'][Math.floor(Math.random() * 4)],
              category: ['技术文档', '用户指南', '研究报告', '案例分析'][Math.floor(Math.random() * 4)],
              wordCount: 200 + Math.floor(Math.random() * 800)
            }
          });
        }
      }
      
      return results;
    } catch (error) {
      console.error('Vector search failed:', error);
      throw new Error('向量检索失败');
    }
  }

  // 混合检索 (向量+关键词)
  async hybridSearch(request: RetrievalRequest): Promise<RetrievalResult[]> {
    const { query, topK, similarityThreshold, filter, hybridSearch, namespace } = request;
    
    try {
      // 1. 向量检索
      const vectorResults = await this.vectorSearch(query, topK, similarityThreshold);
      
      // 如果不是混合搜索，直接返回向量结果
      if (!hybridSearch) {
        return vectorResults;
      }
      
      // 2. 关键词检索 (实际应用中调用全文检索API)
      await new Promise(resolve => setTimeout(resolve, 300));
      
      // 模拟关键词搜索结果
      const keywordResults: RetrievalResult[] = [];
      const keywordCount = Math.floor(topK * 0.7); // 通常关键词结果会少一些
      
      for (let i = 0; i < keywordCount; i++) {
        const score = Math.max(0.4, 0.9 - (i * 0.1) + (Math.random() * 0.1 - 0.05));
        
        if (score >= similarityThreshold) {
          const result: RetrievalResult = {
            id: `key-doc-${i + 1}`,
            title: `${query} 关键词匹配文档 ${i + 1}`,
            content: `这是通过关键词搜索找到的与"${query}"相关的文档内容。关键词搜索对精确匹配特定术语很有效。`,
            source: `https://example.com/keyword-docs/${i + 1}`,
            score: score,
            metadata: {
              matchType: 'keyword',
              matchedTerms: query.split(' '),
              createdAt: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toISOString(),
              category: ['指南', '文档', '博客', '论文'][Math.floor(Math.random() * 4)]
            }
          };
          
          keywordResults.push(result);
        }
      }
      
      // 3. 结果合并与重排序 (实际应用中需要更复杂的融合算法)
      // 简单合并并去重 (基于ID)
      const combinedMap = new Map<string, RetrievalResult>();
      
      // 添加向量结果
      vectorResults.forEach(result => {
        combinedMap.set(result.id, { 
          ...result, 
          metadata: { ...result.metadata, resultType: 'vector' } 
        });
      });
      
      // 添加关键词结果，如果已存在则提升分数
      keywordResults.forEach(result => {
        if (combinedMap.has(result.id)) {
          const existing = combinedMap.get(result.id)!;
          // 提升分数 - 在实际应用中可能需要更复杂的融合策略
          combinedMap.set(result.id, {
            ...existing,
            score: Math.min(1.0, existing.score * 1.2), // 提升20%但不超过1
            metadata: { 
              ...existing.metadata, 
              resultType: 'hybrid',
              hybridBoost: true
            }
          });
        } else {
          combinedMap.set(result.id, { 
            ...result, 
            metadata: { ...result.metadata, resultType: 'keyword' } 
          });
        }
      });
      
      // 转换回数组并按分数排序
      const finalResults = Array.from(combinedMap.values())
        .sort((a, b) => b.score - a.score)
        .slice(0, topK);
      
      return finalResults;
    } catch (error) {
      console.error('Hybrid search failed:', error);
      throw new Error('混合检索失败');
    }
  }

  // 复杂查询方法，支持过滤器和其他高级选项
  async search(request: RetrievalRequest): Promise<RetrievalResult[]> {
    // 调用混合搜索或向量搜索
    return this.hybridSearch(request);
  }
} 